package com.rayson.yututu.service.impl;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rayson.yututu.exception.ErrorCodeEnum;
import com.rayson.yututu.exception.ThrowUtils;
import com.rayson.yututu.mapper.SpaceUserMapper;
import com.rayson.yututu.model.entity.Space;
import com.rayson.yututu.model.entity.SpaceUser;
import com.rayson.yututu.model.entity.User;
import com.rayson.yututu.model.enums.SpaceRoleEnum;
import com.rayson.yututu.model.req.IdRequest;
import com.rayson.yututu.model.req.spaceUser.SpaceUserAddReq;
import com.rayson.yututu.model.req.spaceUser.SpaceUserEditReq;
import com.rayson.yututu.model.req.spaceUser.SpaceUserQueryReq;
import com.rayson.yututu.model.vo.spaceUser.SpaceUserVO;
import com.rayson.yututu.service.SpaceService;
import com.rayson.yututu.service.SpaceUserService;
import com.rayson.yututu.service.UserService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author wulei
 * @description 针对表【space_user(空间成员表)】的数据库操作Service实现
 * @createDate 2025-01-18 20:04:02
 */
@Slf4j
@Service
public class SpaceUserServiceImpl extends ServiceImpl<SpaceUserMapper, SpaceUser>
        implements SpaceUserService {

    @Resource
    private UserService userService;

    @Resource
    private SpaceService spaceService;


    @Override
    public String addSpaceUser(SpaceUserAddReq spaceUserAddReq) {
        SpaceUser spaceUser = new SpaceUser();
        BeanUtils.copyProperties(spaceUserAddReq, spaceUser);
        // 校验
        validSpaceUser(spaceUser, true);
        // 保存
        boolean result = save(spaceUser);
        ThrowUtils.throwIf(!result, ErrorCodeEnum.OPERATION_ERROR, "添加失败");
        return spaceUser.getId();
    }

    @Override
    public SpaceUserVO getSpaceUserVO(SpaceUser spaceUser, HttpServletRequest request) {
        SpaceUserVO spaceUserVO = SpaceUserVO.objToVO(spaceUser);
        // 关联查询用户信息
        User user = userService.getById(spaceUser.getUserId());
        if (Objects.nonNull(user) && StrUtil.isNotBlank(user.getId())) {
            spaceUserVO.setUserVO(user.toUserVO());
        }
        // 关联空间信息
        String spaceId = spaceUser.getSpaceId();
        Space space = spaceService.getById(spaceId);
        if (Objects.nonNull(space) && StrUtil.isNotBlank(space.getId())) {
            spaceUserVO.setSpaceVO(Space.toVO(space));
        }
        return spaceUserVO;
    }

    @Override
    public List<SpaceUserVO> getSpaceUserVOList(List<SpaceUser> spaceUserList) {
        if (CollUtil.isEmpty(spaceUserList)) {
            return Collections.emptyList();
        }
        List<SpaceUserVO> spaceUserVOList = spaceUserList.stream().map(SpaceUserVO::objToVO).collect(Collectors.toList());
        Set<String> userIdSet = spaceUserList.stream().map(SpaceUser::getUserId).collect(Collectors.toSet());
        Set<String> spaceIdSet = spaceUserList.stream().map(SpaceUser::getSpaceId).collect(Collectors.toSet());
        // 批量查询用户信息和空间信息
        Map<String, User> userMap = userService.listByIds(userIdSet).stream()
                .collect(Collectors.toMap(User::getId, Function.identity(), (a, b) -> a));
        Map<String, Space> spaceMap = spaceService.listByIds(spaceIdSet).stream()
                .collect(Collectors.toMap(Space::getId, Function.identity(), (a, b) -> a));
        // 填充用户和空间信息
        spaceUserVOList.forEach(spaceUserVO -> {
            String userId = spaceUserVO.getUserId();
            String spaceId = spaceUserVO.getSpaceId();
            if (userMap.containsKey(userId)) {
                spaceUserVO.setUserVO(userMap.get(userId).toUserVO());
            }
            if (spaceMap.containsKey(spaceId)) {
                spaceUserVO.setSpaceVO(Space.toVO(spaceMap.get(spaceId)));
            }
        });
        return spaceUserVOList;
    }

    @Override
    public QueryWrapper<SpaceUser> getQueryWrapper(SpaceUserQueryReq spaceUserQueryReq) {
        String id = spaceUserQueryReq.getId();
        String spaceId = spaceUserQueryReq.getSpaceId();
        String userId = spaceUserQueryReq.getUserId();
        String spaceRole = spaceUserQueryReq.getSpaceRole();
        // 构造查询参数
        QueryWrapper<SpaceUser> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq(StrUtil.isNotBlank(id), "id", id);
        queryWrapper.eq(StrUtil.isNotBlank(spaceId), "space_id", spaceId);
        queryWrapper.eq(StrUtil.isNotBlank(userId), "user_id", userId);
        queryWrapper.eq(StrUtil.isNotBlank(spaceRole), "space_role", spaceRole);
        return queryWrapper;
    }

    @Override
    public Boolean deleteSpaceUser(IdRequest idRequest) {
        // 无论数据是否存在，执行删除即可
        return removeById(idRequest.getId());
    }

    @Override
    public void editSpaceUser(SpaceUserEditReq editReq) {
        SpaceUser spaceUser = new SpaceUser();
        BeanUtils.copyProperties(editReq, spaceUser);
        validSpaceUser(spaceUser, false);
        String id = editReq.getId();
        SpaceUser old = getById(id);
        ThrowUtils.throwIf(Objects.isNull(old), ErrorCodeEnum.NOT_FOUND_ERROR, "空间用户不存在");
        if (StrUtil.equals(old.getSpaceRole(), editReq.getSpaceRole())) {
            return;
        }
        // 更新数据库
        boolean result = updateById(spaceUser);
        log.info("更新空间用户信息，id：{}，result：{}", id, result);
    }

    @Override
    public void validSpaceUser(SpaceUser spaceUser, boolean add) {
        ThrowUtils.throwIf(Objects.isNull(spaceUser), ErrorCodeEnum.PARAM_ERROR);
        String spaceId = spaceUser.getSpaceId();
        String userId = spaceUser.getUserId();
        if (add) {
            ThrowUtils.throwIf(StrUtil.hasBlank(spaceId, userId), ErrorCodeEnum.PARAM_ERROR);
            ThrowUtils.throwIf(Objects.isNull(userService.getById(userId)), ErrorCodeEnum.NOT_FOUND_ERROR, "用户不存在");
            ThrowUtils.throwIf(Objects.isNull(spaceService.getById(spaceId)), ErrorCodeEnum.NOT_FOUND_ERROR, "空间不存在");
            boolean exists = lambdaQuery()
                    .eq(SpaceUser::getSpaceId, spaceId)
                    .eq(SpaceUser::getUserId, userId)
                    .exists();
            ThrowUtils.throwIf(exists, ErrorCodeEnum.PARAM_ERROR, "用户已在空间内");
        }
        // 校验空间角色
        ThrowUtils.throwIf(!SpaceRoleEnum.isSpaceRoleEnum(spaceUser.getSpaceRole()), ErrorCodeEnum.PARAM_ERROR, "空间角色不存在");
    }
}




